
import AMapLoader from '@amap/amap-jsapi-loader';
import * as THREE from 'three'

let mapCenter = [120.64688,30.783979]
export let camera: THREE.PerspectiveCamera
export let renderer: THREE.WebGLRenderer
export let scene: THREE.Scene = new THREE.Scene();

export type CreateAMapType = {
    map: any,
    AMap: any,
    customCoords: any


}
export type CreateGLCustomLayerType = {
    customLayer: any
}
export const createAMap: () => Promise<CreateAMapType & CreateGLCustomLayerType> = () => {
    return new Promise((resolve, reject) => {
        AMapLoader.load({
            "key": "e4837115d42c13263434bcfd48074dcc",              // 申请好的Web端开发者Key，首次调用 load 时必填
            "version": "2.0",
            "Loca": {
                version: '2.0.0'
            },
        }).then(async (res) => {
            // 创建地图
            var map = new res.Map("container", {
                resizeEnable: true,
                center: mapCenter,//地图中心点
                zoom: 18, //地图显示的缩放级别
                viewMode: '3D',//开启3D视图,默认为关闭
                // buildingAnimation: true,//楼块出现是否带动画
                pitch: 35,
                // features: ['bg', 'road'],
                showLabel: false,
                zIndex: 9,

            });
            // 自定义图层
            var customCoords = map.customCoords;
            const center = map.getCenter()
            customCoords = map.customCoords;

            customCoords.setCenter([center.lng, center.lat]);

            const { customLayer } = await createGLCustomLayer(res, customCoords)

            map.add(customLayer);

            resolve({ map, AMap: res, customLayer, customCoords })
        })
    })
}

var createGLCustomLayer = (AMap: any, customCoords: any): Promise<CreateGLCustomLayerType> => {
    return new Promise((resolve) => {
        const customLayer = new AMap.GLCustomLayer({
            // 图层的层级
            zIndex: 110,
            // 初始化的操作，创建图层过程中执行一次。
            init: async (gl: any) => {
                // 这里我们的地图模式是 3D，所以创建一个透视相机，相机的参数初始化可以随意设置，因为在 render 函数中，每一帧都需要同步相机参数，因此这里变得不那么重要。
                // 如果你需要 2D 地图（viewMode: '2D'），那么你需要创建一个正交相机
                camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 30);

                renderer = new THREE.WebGLRenderer({
                    context: gl,  // 地图的 gl 上下文
                });

                // 自动清空画布这里必须设置为 false，否则地图底图将无法显示
                renderer.autoClear = false;

                // 环境光照和平行光
                var aLight = new THREE.AmbientLight(0xffffff, 0.3);
                var dLight = new THREE.DirectionalLight(0xffffff, 1);
                dLight.position.set(1000, -100, 900);
                scene.add(dLight);
                scene.add(aLight);
                scene.add(new THREE.AxesHelper(70))
            },
            render: () => {
                // 这里必须执行！！重新设置 three 的 gl 上下文状态。
                renderer.resetState();
                // 重新设置图层的渲染中心点，将模型等物体的渲染中心点重置
                // 否则和 LOCA 可视化等多个图层能力使用的时候会出现物体位置偏移的问题
                var { near, far, fov, up, lookAt, position } = customCoords.getCameraParams();
                // 这里的顺序不能颠倒，否则可能会出现绘制卡顿的效果。
                camera.near = near;
                camera.far = far;
                camera.fov = fov;
                camera.position.copy(new THREE.Vector3().fromArray(position))
                camera.up.set(up[0], up[1], up[2]);
                camera.lookAt(lookAt[0], lookAt[1], lookAt[2]);
                camera.updateProjectionMatrix();

                renderer.render(scene, camera);

                // 这里必须执行！！重新设置 three 的 gl 上下文状态。
                renderer.resetState();
                
                map.render();
            },
        });
        resolve({
            customLayer
        })
    })

}

export const { map, AMap, customLayer, customCoords } = await createAMap()